package esUtility

import (
	//	"EsTag/esUtility"

	"time"
	//      "AntLinkCampus/CampusServer/apps/antCron"
	"fmt"
	//	"reflect"
	//	"EsTag/mysqlUtility"

	"github.com/astaxie/beego"
	"golang.org/x/net/context"
	elastic "gopkg.in/olivere/elastic.v5"
)

// DbConfig 数据库连接参数
//type DbConfig struct {
//      IP   string
//      Port int64
//}
var Ctx context.Context
var Client *elastic.Client

func init() {
	fmt.Println("正在初始化es")
	Ctx = context.Background()
	hostStr := beego.AppConfig.String("elasticsearch::host")
	port := beego.AppConfig.String("elasticsearch::port")

	userStr := beego.AppConfig.String("elasticsearch::user")
	pwdStr := beego.AppConfig.String("elasticsearch::pwd")
	if hostStr == "" {
		//		hostStr = "60.205.59.210"
		hostStr = "127.0.0.1"
	}
	if port == "" {
		port = "9200"
	}
	if userStr == "" {
		userStr = "es"
	}
	if pwdStr == "" {
		pwdStr = "kRNj0K"
	}
	uri := "http://" + hostStr + ":" + port
	fmt.Println(uri)
	//      Client, _ = elastic.NewClient(elastic.SetURL("http://60.205.59.210:9200"), elastic.SetBasicAuth("es", "kRNj0K"))
	//      Client, _ = elastic.NewClient(elastic.SetURL(uri), elastic.SetBasicAuth("es", "kRNj0K"))
	Client, _ = elastic.NewClient(elastic.SetURL(uri), elastic.SetBasicAuth(userStr, pwdStr))

}

func IsIndexExist(indexName string) (bool, error) {
	exists, err := Client.IndexExists(indexName).Do(Ctx)
	if err != nil {
		return false, err
	}
	if !exists {
		return false, nil
	}
	return true, nil
}

func InsertDocToEs(indexName string, tableName string, object interface{}) (bool, error) {
	// Add a document to the index
	_, err := Client.Index().
		Index(indexName).
		Type(tableName).
		BodyJson(object).
		Refresh("true").
		Do(Ctx)
	if err != nil {
		return false, err
	}

	//      fmt.Println(result)
	return true, nil
}

// InsertMultiDocsToES 插入多条数据到es
func InsertMultiDocsToES(iname, tname string, objs ...interface{}) (err error) {

	bulk := elastic.NewBulkService(Client)

	for _, obj := range objs {
		ireq := elastic.NewBulkIndexRequest()
		ireq = ireq.Index(iname).Type(tname).Doc(obj)
		bulk.Add(ireq)
	}

	//      _, err = bulk.Do(context.Background())
	_, err = bulk.Do(Ctx)
	return
}

func DeleteIndexByName(index string) (bool, error) {
	// Delete tweet with specified ID  Type(tableName).
	res, err := Client.DeleteIndex(index).Do(Ctx)
	if err != nil {
		// Handle error
		//           panic(err)
		return false, err
	}
	if !res.Acknowledged {
		fmt.Print("Document deleted  from index\n")
	}
	return true, nil
}

func QueryByUserId(indexName string, tableName string, userId int64) (int64, error) {
	// Search with a term query
	termQuery := elastic.NewTermQuery("User.UId", userId)
	searchResult, err := Client.Search().
		Index(indexName). // search in index "twitter"
		//            Type(tableName).
		Query(termQuery). // specify the query
		//            Sort("UserName", true). // sort by "user" field, ascending
		//            From(0).Size(10).        // take documents 0-9
		Pretty(true). // pretty print request and response JSON
		Do(Ctx)       // execute
	if err != nil {
		// Handle error
		fmt.Println(err.Error())
		return -1, err
	}

	return searchResult.TotalHits(), nil
}

func CreateTagIndex(indexstr string) (bool, error) {

	exists, err := Client.IndexExists(indexstr).Do(Ctx)
	if err != nil {
		fmt.Println("IndexExists失败===================22222222222")
		panic("IndexExists失败")
	}

	if !exists {
		mapping := `
{
     "settings": {
          "index.mapping.total_fields.limit": 10000
     },
     "mappings": {
          "_default_": {
               "date_detection": false
          },        
          "tagUser": {           
             "properties": { 
             "TagUser.Xg.IntelUserCode": { "type":      "keyword"      }
               }
          }
     }
}
`

		createIndex, err := Client.CreateIndex(indexstr).BodyString(mapping).Do(Ctx)
		if err != nil {
			// Handle error
			fmt.Println("创建index失败=============1111111111111111" + indexstr)
			panic(err)
		}
		if !createIndex.Acknowledged {
			fmt.Println("es创建index失败===================22222222222" + indexstr)
			panic("Not acknowledged")
		}

	} else {
		fmt.Println("索引尚未删除成功 进入递归===================" + indexstr)
		// 10s
		time.Sleep(10000000000)
		CreateTagIndex(indexstr)
	}

	return true, nil

}

// InsertTagMultiDocsToES 插入多条数据到es
func InsertTagMultiDocsToES(iname, tname string, objs ...interface{}) (err error) {

	bulk := elastic.NewBulkService(Client)

	for _, obj := range objs {
		ireq := elastic.NewBulkIndexRequest()
		ireq = ireq.Index(iname).Type(tname).Id(obj.(*TagUser).Xg.University + obj.(*TagUser).Xg.UUserCode).Doc(obj)
		bulk.Add(ireq)
	}

	//      _, err = bulk.Do(context.Background())
	_, err = bulk.Do(Ctx)
	return
}

//追加mongodb数据库
func InsertTagMultiMongodb(iname, tname string, objs []JjhModel) (err error) {

	bulk := elastic.NewBulkService(Client)

	for _, obj := range objs {
		// 存在修改 不存在新增
		fmt.Println(obj.Usercode)
		if obj.Usercode == "" {
			//			fmt
			ireq := elastic.NewBulkIndexRequest()
			ireq = ireq.Index(iname).Type(tname).Id(obj.University + obj.Uid).Doc(map[string]interface{}{"Jjh": obj})
			bulk.Add(ireq)

		} else {
			update := elastic.NewBulkUpdateRequest()
			//			script := elastic.NewScript("ctx._source.Jjh = obj")
			//			script = script.Params(map[string]interface{}{"obj": obj})
			update = update.Index(iname).Type(tname).Id(obj.University + obj.Usercode).Doc(map[string]interface{}{"Jjh": obj}).DocAsUpsert(true)

			bulk.Add(update)
		}
	}
	if bulk.NumberOfActions() == 0 {
		return
	}

	//      _, err = bulk.Do(context.Background())
	_, err = bulk.Do(Ctx)
	return
}

func QueryById(indexName string, tableName string, userId int64) (int64, error) {

	termQuery := elastic.NewTermQuery("TagUser.Xg.UUserCode", userId)
	searchResult, err := Client.Search().
		Index(indexName). // search in index "twitter"
		//            Type(tableName).
		Query(termQuery). // specify the query
		//            Sort("UserName", true). // sort by "user" field, ascending
		//            From(0).Size(10).        // take documents 0-9
		Pretty(true). // pretty print request and response JSON
		Do(Ctx)       // execute
	if err != nil {
		// Handle error
		fmt.Println(err.Error())
		return -1, err
	}

	return searchResult.TotalHits(), nil
}
